#include "tk_filesystem.h"
#include <QDir>
#include <QFile>
#include <QDataStream>
#include <assert.h>

#ifdef Q_OS_WIN
#	include <windows.h>
#endif // Q_OS_WIN


namespace tk
{
	tk_bool PathExist(QString path)
	{
		return QFile::exists(QDir::toNativeSeparators(path));
	}

	tk_bool PathCreate(QString path)
	{
		QDir dir;
		return dir.mkpath(QDir::toNativeSeparators(path));
	}

	tk_bool PathCreateFromFilePath(QString path)
	{
		QFileInfo file(QDir::toNativeSeparators(path));
		QDir dir;
		return dir.mkpath(file.path());
	}

	tk_bool PathDelete(QString path)
	{
		QDir _dir(QDir::toNativeSeparators(path));
		if (!PathExist(path))
		{
			return TK_TRUE;
		}
		return _dir.removeRecursively();
	}

	tk_bool FileDelete(QString path)
	{
		QDir _dir(QDir::toNativeSeparators(path));
		if (!PathExist(path))
		{
			return TK_TRUE;
		}
		return QFile::remove(path);
	}

	tk_bool FileCopy(QString from_path, QString to_path)
	{
		return QFile::copy(from_path, to_path);
	}

	tk_bool FileRename(QString old_name, QString new_name)
	{
		return QFile::rename(old_name, new_name);
	}

	tk_bool WriteBinaryFile(QString path, std::vector<tk_uchar> & data)
	{
		path = QDir::toNativeSeparators(path);
		if (!PathCreateFromFilePath(path))
		{
			return TK_FALSE;
		}
		QFile file(path);
		file.remove(path);
		if (file.open(QIODevice::WriteOnly))
		{
			QDataStream datastream(&file);
			datastream.writeRawData((const tk_pchar)(data.data()), data.size());
			file.flush();
			file.close();
			FlushFileToDisk(path);
			return TK_TRUE;
		}
		return TK_FALSE;
	}

	tk_bool ReadBinaryFile(QString path, std::vector<tk_uchar> & data)
	{
		QFile file(QDir::toNativeSeparators(path));
		if (file.exists() && file.open(QIODevice::ReadOnly))
		{
			if (file.size())
			{
				data.resize(file.size());
				QDataStream datastream(&file);
				datastream.readRawData((tk_pchar)data.data(), file.size());
			}
			file.close();
		}
		return data.size() != 0;
	}

	void FlushFileToDisk(QString file_path)
	{
#ifdef Q_OS_WIN
		QString path = QDir::toNativeSeparators(file_path);
		std::wstring pathw = path.toStdWString();
		HANDLE phandle = CreateFileW(pathw.c_str(),GENERIC_READ|GENERIC_WRITE,
			0,NULL,OPEN_ALWAYS,
			FILE_ATTRIBUTE_NORMAL,NULL);
		tk_bool bRet = (tk_bool)FlushFileBuffers(phandle);
		assert(bRet);
		CloseHandle(phandle);
#endif // Q_OS_WIN

	}
}//namespace tk
